﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using log4net;

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Service
{
    public class WindowsAPIService:IWindowAPI
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Nullable));

        #region  函数值
        private const uint BM_CLICK = 0xF5; //鼠标点击的API
        const int WM_GETTEXT = 0xd;//获取文本
        public static int WM_CHAR = 0x102;
        public static int WM_CLICK = 0x00F5;
        private const uint LVM_FIRST = 0x1000;
        private const uint LVM_GETHEADER = LVM_FIRST + 31;
        private const uint LVM_GETITEMCOUNT = LVM_FIRST + 4;//获取列表行数
        private const uint LVM_GETITEMTEXT = LVM_FIRST + 45;//获取列表内的内容
        private const uint LVM_GETITEMW = LVM_FIRST + 75;

        private const uint HDM_GETITEMCOUNT = 0x1200;//获取列表列数

        private const uint PROCESS_VM_OPERATION = 0x0008;//允许函数VirtualProtectEx使用此句柄修改进程的虚拟内存
        private const uint PROCESS_VM_READ = 0x0010;//允许函数访问权限
        private const uint PROCESS_VM_WRITE = 0x0020;//允许函数写入权限

        private const uint MEM_COMMIT = 0x1000;//为特定的页面区域分配内存中或磁盘的页面文件中的物理存储
        private const uint MEM_RELEASE = 0x8000;
        private const uint MEM_RESERVE = 0x2000;//保留进程的虚拟地址空间,而不分配任何物理存储

        private const uint PAGE_READWRITE = 4;

        //const int MOUSEEVENTF_MOVE = 0x0001;
        ////模拟鼠标左键按下 
        //const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        ////模拟鼠标左键抬起 
        //const int MOUSEEVENTF_LEFTUP = 0x0004;
        ////模拟鼠标右键按下 
        //const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
        ////模拟鼠标右键抬起 
        //const int MOUSEEVENTF_RIGHTUP = 0x0010;
        ////模拟鼠标中键按下 
        //const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        ////模拟鼠标中键抬起 
        //const int MOUSEEVENTF_MIDDLEUP = 0x0040;
        ////标示是否采用绝对坐标 
        //const int MOUSEEVENTF_ABSOLUTE = 0x8000;

        private const int WM_SETTEXT = 0x000C;
        #endregion

        #region WindowsAPI
        //窗体句柄
        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

     
        //控件句柄
        [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);


        //活动窗体
        [DllImport("user32.dll")]
        private static extern void SetForegroundWindow(IntPtr hwnd);

        //打开窗体
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "MoveWindow")]
        public static extern bool MoveWindow(System.IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);


        [DllImport("user32.dll", CharSet = CharSet.Ansi)]
        public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

        [DllImport("user32.dll")]
        public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);


        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll", EntryPoint = "GetWindowText")]
        public static extern int GetWindowText(
          IntPtr hWnd,
          StringBuilder lpString,
          int nMaxCount
      );
        [DllImport("kernel32")]//ini读
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);


        [DllImport("kernel32")]//ini写
        private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);

        [DllImport("user32.dll")]
        private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);


        public delegate bool CallBack(IntPtr hwnd, int lParam);

        [DllImport("user32.dll")]
        private static extern int RealGetWindowClass(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, uint nMaxCount);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr Hwnd, int Msg, int wpala, string lpala);

        [DllImport("user32.dll", EntryPoint = "SendMessageA")]
        static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr Hwnd, int Msg, int wpala, int lpala);

        [DllImport("user32.dll")]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);


        public void SendChar(IntPtr hand, char ch, int SleepTime)
        {
            PostMessage(hand, WM_CHAR, ch, 0);
            System.Threading.Thread.Sleep(SleepTime);
        }

        [DllImport("user32.dll", EntryPoint = "WindowFromPoint")]//指定坐标处窗体句柄
        public static extern int WindowFromPoint(
     int xPoint,
     int yPoint
 );
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        //[DllImport("user32.dll", EntryPoint = "ChildWindowFromPoint"),CallingConvention = CallingConvention.Cdecl)]//指定坐标处窗体句柄
        public static extern int ChildWindowFromPoint(
    int xPoint,
    int yPoint
);
        public int APIChildWindowFromPoint(
    int xPoint,
    int yPoint
)
        {
       return ChildWindowFromPoint(xPoint,yPoint);
    }
        [DllImport("user32.dll")]
        private static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);

        [DllImport("user32.dll")]
        private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);

        public int APIGetWindowRect(IntPtr hwnd, out Rect lpRect)
        {
        
          int a=  GetWindowRect(hwnd, out lpRect);

            return a;
        }
        public struct Rect
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }


        [Flags]
        enum MouseEventFlag : uint
        {
            Move = 0x0001,
            LeftDown = 0x0002,
            LeftUp = 0x0004,
            RightDown = 0x0008,
            RightUp = 0x0010,
            MiddleDown = 0x0020,
            MiddleUp = 0x0040,
            XDown = 0x0080,
            XUp = 0x0100,
            Wheel = 0x0800,
            VirtualDesk = 0x4000,
            Absolute = 0x8000
        }
        //移动鼠标
        [DllImport("user32")]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);


        [DllImport("user32")]
        public extern static void SetCursorPos(int x, int y);

        const int MOUSEEVENTF_MOVE = 0x0001;     // 移动鼠标           (十):1
        const int MOUSEEVENTF_LEFTDOWN = 0x0002; //模仿鼠标左键按下    (十):2
        const int MOUSEEVENTF_LEFTUP = 0x0004; //模仿鼠标左键抬起    (十):4
        const int MOUSEEVENTF_RIGHTDOWN = 0x0008; //模仿鼠标右键按下    (十):8
        const int MOUSEEVENTF_RIGHTUP = 0x0010; //模仿鼠标右键抬起    (十):16
        const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;// 模仿鼠标中键按下    (十):32
        const int MOUSEEVENTF_MIDDLEUP = 0x0040;// 模仿鼠标中键抬起    (十):64
        const int MOUSEEVENTF_ABSOLUTE = 0x8000; //标示是否采取绝对坐标    (十):32768

        [StructLayout(LayoutKind.Sequential)]
        struct NativeRECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }


        delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern bool BlockInput([In, MarshalAs(UnmanagedType.Bool)] bool fBlockIt);

        //根据句柄获取坐标
        [DllImport("user32.dll")]
        static extern bool GetWindowRect(IntPtr hwnd, ref NativeRECT rect);

        #endregion
        //打开窗体方法
        public void APIOpenAndSetWindow(String fileName)
        {
            Process p = new Process();
            p.StartInfo.FileName = fileName;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            p.Start();
            new Thread(() =>
            {
                Thread.Sleep(1000);
                if (p != null && p.MainWindowHandle != IntPtr.Zero)
                {
                    MoveWindow(p.MainWindowHandle, 600, 1000, 500, 400, true);
                }
            }).Start();
        }
        //重写API
        public IntPtr APIFindWindow(string lpClassName, string lpWindowName)
        {
            return FindWindow(lpClassName, lpWindowName);
        }
        public long APIWritePrivateProfileString(string section, string key, string val, string filePath)
        {
            return WritePrivateProfileString(section,key,val,filePath);
        }
        public  int APIGetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath)
        {
            return GetPrivateProfileString( section,  key,  defVal,  retVal,  size,  filePath);
        }

        public IntPtr APIFindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow)
        {
            return FindWindowEx(
                hwndParent: hwndParent,
                hwndChildAfter: hwndChildAfter,
                lpszClass: lpszClass,
                lpszWindow :lpszWindow);
        }
        public int APISetSendMessage(IntPtr Hwnd, int Msg, int wpala, string lpala)
        {
            return SendMessage(Hwnd: Hwnd, Msg: Msg, wpala: wpala, lpala: lpala);
        }
        public int APIGetSendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam)
        {
            return  SendMessage(hwnd: hwnd, wMsg: wMsg, wParam: wParam, lParam: lParam);
        }
        public int APIClickSendMessage(IntPtr Hwnd, int Msg, int wpala, int lpala)
        {
            return SendMessage( Hwnd,  Msg,  wpala,  lpala);
        }
        public int APIWindowFromPoint(int xPoint, int yPoint)
        {
            return WindowFromPoint(xPoint:xPoint,yPoint:yPoint);
        }
        public void APISetForegroundWindow(IntPtr hwnd)
        {
            SetForegroundWindow(hwnd);
        }
        public void APISetCursorPos(int x, int y)
        {
            SetCursorPos(x,y);
        }
        public int APIShowWindow(IntPtr hwnd, int nCmdShow)
        {
            return ShowWindow(hwnd, nCmdShow);
        }
        public bool APIBlockInput(bool Block)
        {
           return  BlockInput(Block);
        }
        public void APImouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo)
        {
            mouse_event( dwFlags,  dx,  dy,  dwData,  dwExtraInfo);
        }
        public IntPtr APIPostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam)
        {
            return PostMessage( hwnd,  wMsg,  wParam,  lParam);
        }
        public int APISetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags)
        {
            return SetWindowPos( hWnd,  hWndInsertAfter,  x,  y,  Width,  Height,  flags);
        }
        public int APIGetWindowText(
          IntPtr hWnd,
          StringBuilder lpString,
          int nMaxCount
      )
        {
         return   GetWindowText( hWnd,lpString,nMaxCount);
        }


        [StructLayout(LayoutKind.Sequential)]
        public class POINT
        {
            public int x;
            public int y;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class MouseHookStruct
        {
            public POINT pt;
            public int hwnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        //安装钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        //卸载钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        //调用下一个钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowTextLength(IntPtr hwnd);

        public int APIGetWindowTextLength(IntPtr hwnd)
        {
            return GetWindowTextLength(hwnd);
        }
        public string[] GetLocation(IntPtr windows)
        {
            string[] data = new string[2];
            NativeRECT rect = new NativeRECT();

            GetWindowRect(windows, ref rect);

            data[0] = (rect.left).ToString();
            data[1] = (rect.top).ToString();
            return data;
        }
        //模拟键盘发送消息
        public void APICopyData(IntPtr myWindows, IntPtr heWindows,List<string>name, List<int> InfoXY, bool? XYEvent)
        {
            
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^c");
            //SetForegroundWindow(heWindows);
            //SendKeys.SendWait("^v");//Tab到名称文本框复制粘贴
            //Thread.Sleep(1);
            //SetForegroundWindow(myWindows);
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^c");
            //Thread.Sleep(1);
            //SetForegroundWindow(heWindows);
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^v");//Tab到数字文本框复制粘贴

            //Thread.Sleep(1);
            //SetForegroundWindow(myWindows);
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^c");
            //Thread.Sleep(1);
            //SetForegroundWindow(heWindows);
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^v");//Tab到地址电话文本框复制粘贴

            //Thread.Sleep(1);
            //SetForegroundWindow(myWindows);
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^c");
            //Thread.Sleep(1);
            //SetForegroundWindow(heWindows);
            //SendKeys.SendWait("{TAB}");
            //SendKeys.SendWait("^v");//Tab到银行文本框复制粘贴

            //SendKeys.Send("1111高");//发送字符串
            //SendKeys.SendWait("{ }");

            SetForegroundWindow(heWindows);

            //APISetWindowPos(heWindows, -1, 0, 0, 0, 0, 1 | 2);
            //string[] datalist = GetLocation(heWindows);
            //APISetCursorPos(Convert.ToInt32(datalist[0]), Convert.ToInt32(datalist[1]));//移动鼠标
            //APImouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE), 0, 0, 0, IntPtr.Zero);//摁下
            //APISetCursorPos(98, 138);
            //APImouse_event((int)(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE), 0, 0, 0, IntPtr.Zero);//放开

            if (XYEvent.HasValue)
            {
                if (XYEvent.Value)
                {
                    for (int i = 0; i <= 5; i++)
                    {
                        APISetCursorPos(535,397);
                    }
                    APImouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP), 0, 0, 0, IntPtr.Zero);//摁下
                }
            }

            string[] TOP = GetLocation(heWindows);
            int TEST1 = Convert.ToInt32(TOP[0]) + InfoXY[0];
            int TEST2 = Convert.ToInt32(TOP[1]) + InfoXY[1];
            // APISetForegroundWindow(heWindows);
            int AA = APIWindowFromPoint(TEST1, TEST2);
            log.InfoFormat("名称句柄："+AA);
            APISetSendMessage(new IntPtr(AA), WM_SETTEXT, 0, name[0]);

            int TEST3 = Convert.ToInt32(TOP[0]) + InfoXY[2];
            int TEST4 = Convert.ToInt32(TOP[1]) + InfoXY[3];
            //APISetForegroundWindow(heWindows);
            int AA1 = APIWindowFromPoint(TEST3, TEST4);
            log.InfoFormat("纳税人识别号句柄："+AA1);
            //   MessageBox.Show(AA1.ToString());
            APISetSendMessage(new IntPtr(AA1), WM_SETTEXT, 0, name[1]);

            int TEST5 = Convert.ToInt32(TOP[0]) + InfoXY[4];
            int TEST6 = Convert.ToInt32(TOP[1]) + InfoXY[5];
            // APISetForegroundWindow(heWindows);
            int AA2 = APIWindowFromPoint(TEST5, TEST6);
            log.InfoFormat("地址电话句柄："+AA2);
            APISetSendMessage(new IntPtr(AA2), WM_SETTEXT, 0, name[2]);


            int TEST7 = Convert.ToInt32(TOP[0]) + InfoXY[6];
            int TEST8 = Convert.ToInt32(TOP[1]) + InfoXY[7];
            //  APISetForegroundWindow(heWindows);
            int AA3 = APIWindowFromPoint(TEST7, TEST8);
            log.InfoFormat("开户行账号句柄："+AA3);
            APISetSendMessage(new IntPtr(AA3), WM_SETTEXT, 0, name[3]);
           // APISetWindowPos(heWindows, -2, 0, 0, 0, 0, 1 | 2);


        }

        public string GetCompanyData(float X, float Y, float windowsLeft, float windowsTop)
        {
         //   MessageBox.Show(X+"|"+Y);
            StringBuilder invno  = new StringBuilder(1024);//编号
            IntPtr a = APIFindWindow(null, "增值税发票税控开票软件（金税盘版） V2.1.20.160425.01");//作废
            if (a != IntPtr.Zero)
            {
                //   MessageBox.Show("开始");
                APIShowWindow(a, 3);
                APISetForegroundWindow(a);

                Thread.Sleep(500);
                float x1 = (float)635 / 1600 * X;
                float Y1 = (float)432 / 860 * Y;
                x1 = x1 + windowsLeft;
                Y1 = Y1 + windowsTop;
                APISetCursorPos(Convert.ToInt32( x1),Convert.ToInt32( Y1));//移动鼠标
                Thread.Sleep(500);
                APImouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP), 0, 0, 0, IntPtr.Zero);//摁下

                Thread.Sleep(500);
                IntPtr A = APIFindWindow(null, "系统参数设置");
                if (A != IntPtr.Zero)
                {
                    //invno = new StringBuilder(1024);//编号
                    //  MessageBox.Show(A.ToString());

                    string[] TOP = GetLocation(A);

                    float x2 = (float)294 / 1600 * X;
                    float y2 = (float)104 / 860 * Y;
                    int TEST1 = Convert.ToInt32(TOP[0]) +Convert.ToInt32( x2);
                    int TEST2 = Convert.ToInt32(TOP[1]) +Convert.ToInt32( y2) ;
                    int AA = APIWindowFromPoint(TEST1, TEST2);
                    IntPtr hwndThree1 = new IntPtr(AA);
                    APIGetSendMessage(hwndThree1, WM_GETTEXT, 1024, invno);
                    // MessageBox.Show(invno.ToString());
                    // StaffData.StaffNo = invno.ToString();

                    //// MessageBox.Show(StaffData.StaffNo);
                    if (!String.IsNullOrWhiteSpace( invno.ToString()))
                    {
                        APISetForegroundWindow(A);
                        APIShowWindow(A, 3);

                        float x3 =(float) 447 / 1600 * X;
                        float y4 = (float)374 / 1600 * Y;
                        int data1 = Convert.ToInt32(TOP[0]) + Convert.ToInt32(x3);
                        int data2 = Convert.ToInt32(TOP[1]) + Convert.ToInt32(y4);
                        APISetCursorPos(Convert.ToInt32(TOP[0]) + 447, Convert.ToInt32(TOP[1]) + 374);
                        
                        Thread.Sleep(500);
                        APImouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP), 0, 0, 0, IntPtr.Zero);//摁下
                       /// MessageBox.Show(a+"|"+A+"|"+invno.ToString());
                    }
                    else
                    {
                        MessageBox.Show("没有数据");
                    }
                  
                    // MessageBox.Show(invno.ToString());
                }
                else
                {
                    MessageBox.Show("异常");
                }

            }
            else
            {
                MessageBox.Show("没有启动程序");
            }
            return invno.ToString();
        }
    }
}
